package com.cll.learn.rpc.provider.context;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述信息:
 * Spring容器上下文
 * @author CLL
 * @version 1.0
 * @date 2020/9/14 15:46
 */
@Component
public class SpringApplicationContext implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    /**
     * bean对象缓存，放置每次都需要反射获取从Spring容器获取bean实例
     */
    private static Map<String, Class<?>> classCacheMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringApplicationContext.applicationContext = applicationContext;
    }

    /**
     * 根据类型，从Spring的IOC容器中获取单例对象
     * @param clazz 类型
     * @param <T>   泛型支持
     * @return  对象
     */
    public static <T> T getBean(Class<T> clazz){
        return SpringApplicationContext.applicationContext.getBean(clazz);
    }

    /**
     * 根据类名称获取类型
     * @param className 类名称
     * @return  类型
     * @throws ClassNotFoundException   根据类名称未找到类型异常
     */
    public static Class<?> getClass(String className) throws ClassNotFoundException {
        if (!classCacheMap.containsKey(className)) {
            Class<?> forName = Class.forName(className);
            classCacheMap.put(className, forName);
        }
        return classCacheMap.get(className);
    }
}
